package org.lqk.pool.netty;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.pool.ChannelHealthChecker;
import io.netty.util.concurrent.Future;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * Created by bert on 16-5-9.
 */
@Component
public class PooledSocketChannelFactory implements PooledObjectFactory<Channel> {
    @Autowired
    private Bootstrap bootstrap;
    private static Logger log = LoggerFactory.getLogger(PooledSocketChannelFactory.class);
    public PooledObject<Channel> makeObject() throws Exception {
        log.debug("makeObject...");
        Bootstrap bs = bootstrap.clone();
        ChannelFuture f = bs.connect();
        f.sync();
        log.debug("connect...");
        Channel channel = f.channel();
        return new DefaultPooledObject<>(channel);
    }

    public void destroyObject(PooledObject<Channel> p) throws Exception {
        log.debug("destroyObject...");
        Channel channel = p.getObject();
        channel.disconnect();
        channel.close();
    }

    public boolean validateObject(PooledObject<Channel> p) {
        log.debug("validateObject...");
        Channel channel = p.getObject();
        Future<Boolean> f = ChannelHealthChecker.ACTIVE.isHealthy(channel);
        // TODO  待确认
        return f.getNow();
    }

    public void activateObject(PooledObject<Channel> p) throws Exception {
        log.debug("activateObject...");
        Channel channel = p.getObject();
        channel.flush();
    }

    public void passivateObject(PooledObject<Channel> p) throws Exception {
        log.debug("passivateObject...");
        Channel channel = p.getObject();
        channel.flush();
    }

}
